package com.bJian.bJIanOJ.judge.strategy;

import cn.hutool.json.JSONUtil;
import com.bJian.bJIanOJ.model.dto.question.JudgeCase;
import com.bJian.bJIanOJ.model.dto.question.JudgeConfig;
import com.bJian.bJIanOJ.model.dto.question_submit.JudgeInfo;
import com.bJian.bJIanOJ.model.entity.Question;
import com.bJian.bJIanOJ.model.entity.question_submit;
import com.bJian.bJIanOJ.model.enums.JudgeInfoMessageEnum;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class DefaultJudgeStrategy implements JudgeStrategy{
    @Override
    public JudgeInfo doJudge(JudgeContext judgeContext) {

        JudgeInfo judgeInfo = judgeContext.getJudgeInfo();
        List<String> inputList = judgeContext.getInputList();
        List<String> outputList = judgeContext.getOutputList();
        List<JudgeCase> judgeCaseList = judgeContext.getJudgeCaseList();
        Question question = judgeContext.getQuestion();
        question_submit questionSubmit = judgeContext.getQuestionSubmit();


        //获取预期结果输出
        List<String> answerInputList = judgeCaseList.stream().map(JudgeCase::getOutput).collect(Collectors.toList());
        if (outputList.size() != answerInputList.size()) {//对比预期结果与运行结果数是否相同
            judgeInfo.setMessage(JudgeInfoMessageEnum.WRONG_ANSWER.getText());
            return judgeInfo;
        }
        for (int i = 0; i < answerInputList.size(); i++) {//循环比对每一组运行结果
            if (!answerInputList.get(i).equals(outputList.get(i))) {
                judgeInfo.setMessage(JudgeInfoMessageEnum.WRONG_ANSWER.getText() + "运行结果：" + outputList.get(i) + ",预期结果：" + answerInputList.get(i));
                return judgeInfo;
            }
        }
        // 判断题目限制
        JudgeConfig judgeConfig = JSONUtil.toBean(question.getJudgeConfig(), JudgeConfig.class);
        Long needTimeLimit = judgeConfig.getTimeLimit();
        Long needMemoryLimit = judgeConfig.getMemoryLimit();

        Long runTime = judgeInfo.getTime();
        Long runMemory = Optional.ofNullable(judgeInfo.getMemory()).orElse(999L);
        if (runTime > needTimeLimit) {
            judgeInfo.setMessage(JudgeInfoMessageEnum.TIME_LIMIT_EXCEEDED.getText());
            return judgeInfo;
        }
        if (runMemory > needMemoryLimit) {
            judgeInfo.setMessage(JudgeInfoMessageEnum.MEMORY_LIMIT_EXCEEDED.getText());
            return judgeInfo;
        }
        judgeInfo.setMessage(JudgeInfoMessageEnum.ACCEPTED.getValue());
        return judgeInfo;
    }
}
